﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.OLE.Interop;
using System.ComponentModel.Design;

namespace FixtureHighlighter
{
    [PackageRegistration(UseManagedResourcesOnly = true, RegisterUsing = RegistrationMethod.CodeBase)]
    [ProvideLoadKey("Standard", "1.0.0.0", "FixtureHighlighter", "CRRC", 1)]
    [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")]
    [InstalledProductRegistration(true, "#110", "#112", "1.0", IconResourceID = 400)]
    [ProvideService(typeof(FixtureLanguageService))]
    [ProvideLanguageExtension(typeof(FixtureLanguageService), FixtureContstants.Extension)]
    [ProvideLanguageService(typeof(FixtureLanguageService), FixtureContstants.LanguageName, 0,
        CodeSense = true,
        EnableCommenting = true,
        MatchBraces = false,
        ShowCompletion = false,
        ShowMatchingBrace = false,
        AutoOutlining = false,
        EnableAsyncCompletion = false,
        EnableFormatSelection = false,
        EnableLineNumbers = true,
        
        RequestStockColors = true,
        CodeSenseDelay = 0)]
    [Guid(FixtureContstants.PackageGuid)]
    public partial class FixturePackage : Package, IOleComponent
    {
        uint _componentID = 0;
        FixtureLanguageService _language;

        public FixturePackage()
        {
            ServiceCreatorCallback callback = new ServiceCreatorCallback(CreateService);
            ((IServiceContainer)this).AddService(typeof(FixtureLanguageService), callback, true);
        }

        object CreateService(IServiceContainer container, Type serviceType)
        {
            if (serviceType == typeof(FixtureLanguageService))
            {
                if (_language == null)
                {
                    _language = new FixtureLanguageService();
                    _language.SetSite(this);

                    // register for idle time callbacks
                    IOleComponentManager mgr = GetService(typeof(SOleComponentManager)) as IOleComponentManager;
                    if (_componentID == 0 && mgr != null)
                    {
                        OLECRINFO[] crinfo = new OLECRINFO[1];
                        crinfo[0].cbSize = (uint)Marshal.SizeOf(typeof(OLECRINFO));
                        crinfo[0].grfcrf = (uint)(_OLECRF.olecrfNeedIdleTime | _OLECRF.olecrfNeedPeriodicIdleTime);
                        crinfo[0].grfcadvf = (uint)(_OLECADVF.olecadvfModal | _OLECADVF.olecadvfRedrawOff | _OLECADVF.olecadvfWarningsOff);
                        crinfo[0].uIdleTimeInterval = 1000;
                        mgr.FRegisterComponent(this, crinfo, out _componentID);
                    }
                }

                return _language;
            }
            else
            {
                return null;
            }
        }

        protected override void Dispose(bool disposing)
        {
            try
            {
                if (_componentID != 0)
                {
                    IOleComponentManager mgr = GetService(typeof(SOleComponentManager)) as IOleComponentManager;
                    if (mgr != null)
                        mgr.FRevokeComponent(_componentID);

                    _componentID = 0;
                }
            }
            finally
            {
                base.Dispose(disposing);
            }
        }

        #region IOleComponent Members

        public int FContinueMessageLoop(uint uReason, IntPtr pvLoopData, MSG[] pMsgPeeked)
        {
            return 1;
        }

        public int FDoIdle(uint grfidlef)
        {
            if (_language != null)
                _language.OnIdle((grfidlef & (uint)_OLEIDLEF.oleidlefPeriodic) != 0);

            return 0;
        }

        public int FPreTranslateMessage(MSG[] pMsg)
        {
            return 0;
        }

        public int FQueryTerminate(int fPromptUser)
        {
            return 1;
        }

        public int FReserved1(uint dwReserved, uint message, IntPtr wParam, IntPtr lParam)
        {
            return 1;
        }

        public IntPtr HwndGetWindow(uint dwWhich, uint dwReserved)
        {
            return IntPtr.Zero;
        }

        public void OnActivationChange(IOleComponent pic, int fSameComponent, OLECRINFO[] pcrinfo, int fHostIsActivating, OLECHOSTINFO[] pchostinfo, uint dwReserved)
        {
        }

        public void OnAppActivate(int fActive, uint dwOtherThreadID)
        {
        }

        public void OnEnterState(uint uStateID, int fEnter)
        {
        }

        public void OnLoseActivation()
        {
        }

        public void Terminate()
        {
        }

        #endregion
    }
}
